package com.example.demo.spring.aop.proxy;

import com.example.demo.spring.aop.util.StringUtils;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * @author: htc
 * @date: Created in 14:22 2019/2/20.
 */
public abstract class AbsMethodAdvance implements MethodInterceptor {
    /**
     * 要被代理的目标对象
     */
    private Object targetObject;

    /**
     * 被代理的方法名
     */
    private String proxyMethodName;

    /**
     * 根据被代理对象 创建代理对象
     *
     * @param target
     * @return
     */
    public Object createProxyObject(Object target) {
        this.targetObject = target;
        //该类用于生成代理对象
        Enhancer enhancer = new Enhancer();
        //设置目标类为代理对象的父类
        enhancer.setSuperclass(this.targetObject.getClass());
        //设置回调用对象为本身
        enhancer.setCallback(this);

        return enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        Object result;

        String proxyMethod = getProxyMethodName();

        if (StringUtils.isNotBlank(proxyMethod) && proxyMethod.equals(method.getName())) {
            doBefore();
        }

        //执行拦截的方法,因为是代理目标的父类，所以执行的是父类方法
        result = methodProxy.invokeSuper(o, objects);

        if (StringUtils.isNotBlank(proxyMethod) && proxyMethod.equals(method.getName())){
            doAfter();
        }

        return result;
    }

    public abstract void doBefore();

    public abstract void doAfter();

    public String getProxyMethodName() {
        return proxyMethodName;
    }

    public void setProxyMethodName(String proxyMethodName) {
        this.proxyMethodName = proxyMethodName;
    }
}
